package com.erlang4j.api;

import java.util.Set;

import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangPid;
import com.ericsson.otp.erlang.OtpErlangPort;
import com.ericsson.otp.erlang.OtpErlangRef;
import com.ericsson.otp.erlang.OtpErlangTuple;
import com.erlang4j.api.exceptions.Erland4jDataTypeCastException;
import com.erlang4j.api.exceptions.Erlang4jKeyNotFoundException;
import com.erlang4j.api.exceptions.Erlang4jOutOfRangeException;

/**
 * <p>
 * Given a key return the item represented by that key narrowed to a specific type
 * </p>
 * <p>
 * Design notes
 * <ul>
 * <li>This could easily have been part of the {@link IBinding} interface . However there are places that just want to
 * process the binding and not make new ones, and this is a huge interface that hides the essence of what a binding is
 * <li>The Exceptions are run time exceptions so that you don't pollute your code, and have to propagate them.
 * <li>The keySet() can return the keys in any order, which means that testing may be awkward
 * </ul>
 * </p>
 * 
 * @author Phil Rice
 */
public interface IGetData {
	/**
	 * @return the raw erlang object represented by the key
	 */
	OtpErlangObject getRaw(String key) throws Erlang4jKeyNotFoundException;

	/**
	 * @return the raw erlang object must be a string , and this is its value
	 */
	String getString(String key) throws Erland4jDataTypeCastException, Erlang4jKeyNotFoundException;

	/**
	 * @return the raw erlang object must be an atom , and this is its value
	 */
	String getAtom(String key) throws Erland4jDataTypeCastException, Erlang4jKeyNotFoundException;

	/**
	 * @return the raw erlang object must be an integer , and this is its value
	 */
	int getInt(String key) throws Erland4jDataTypeCastException, Erlang4jKeyNotFoundException, Erlang4jOutOfRangeException;

	/**
	 * @return the raw erlang object must be an integer , and this is its value
	 */
	long getLong(String key);

	/**
	 * @return the raw erlang object must be an double , and this is its value
	 */
	Double getDouble(String key);

	/**
	 * @return the raw erlang object must be a tuple , and this is its value
	 */
	OtpErlangTuple getTuple(String key) throws Erland4jDataTypeCastException, Erlang4jKeyNotFoundException;

	/**
	 * @return the raw erlang object must be a list , and this is its value
	 */
	OtpErlangList getList(String key) throws Erland4jDataTypeCastException, Erlang4jKeyNotFoundException;

	/**
	 * @return the raw erlang object must be a Pid , and this is its value
	 */
	OtpErlangPid getPid(String key) throws Erland4jDataTypeCastException, Erlang4jKeyNotFoundException;

	/**
	 * @return the raw erlang object must be a Port , and this is its value
	 */
	OtpErlangPort getPort(String key) throws Erland4jDataTypeCastException, Erlang4jKeyNotFoundException;

	/**
	 * @return the raw erlang object must be a ref , and this is its value
	 */
	OtpErlangRef getRef(String key) throws Erland4jDataTypeCastException, Erlang4jKeyNotFoundException;

	Set<String> keySet();
}
